Add a new CARGO_MANIFEST_DIR environment variable
authorAlex Crichton <alex@alexcrichton.com>
Mon, 25 Aug 2014 12:40:47 +0000 (05:40 -0700)
committerAlex Crichton <alex@alexcrichton.com>
Mon, 25 Aug 2014 12:48:51 +0000 (05:48 -0700)
All subprocesses will now be invoked with CARGO_MANIFEST_DIR pointing at the
root of the source directory that they are working on (compiling). This commit
also reorganizes the version environment variables to use the new
infrastructure.

Closes #433

src/cargo/ops/cargo_run.rs
src/cargo/ops/cargo_rustc/compilation.rs
src/cargo/ops/cargo_rustc/context.rs
src/cargo/ops/cargo_rustc/mod.rs
src/cargo/ops/cargo_test.rs
tests/test_cargo_compile.rs

index 67a1f7c2fb0b296bd1b22baa8056519425a89ed2..0862f27322cb73cf628302173d7a300560a9330b 100644 (file)
@@ -22,7 +22,7 @@ pub fn run(manifest_path: &Path,
         Some(path) => path,
         None => exe,
     };
-    let process = compile.process(exe).args(args);
+    let process = compile.process(exe, &root).args(args).cwd(os::getcwd());
 
     try!(options.shell.status("Running", process.to_string()));
     Ok(process.exec().err())
index 6a1a740bb9377a291dcaa01f554545d12d28e01d..fb135ded046d42525ee9c7ff2945dfbf6d3d4391 100644 (file)
@@ -1,8 +1,9 @@
 use std::collections::HashMap;
 use std::dynamic_lib::DynamicLibrary;
 use std::os;
+use semver::Version;
 
-use core::PackageId;
+use core::{PackageId, Package};
 use util;
 
 /// A structure returning the result of a compilation.
@@ -51,7 +52,11 @@ impl Compilation {
 
     /// Prepares a new process with an appropriate environment to run against
     /// the artifacts produced by the build process.
-    pub fn process<T: ToCStr>(&self, cmd: T) -> util::ProcessBuilder {
+    ///
+    /// The package argument is also used to configure environment variables as
+    /// well as the working directory of the child process.
+    pub fn process<T: ToCStr>(&self, cmd: T, pkg: &Package)
+                              -> util::ProcessBuilder {
         let mut search_path = DynamicLibrary::search_path();
         for dir in self.native_dirs.values() {
             search_path.push(dir.clone());
@@ -64,6 +69,31 @@ impl Compilation {
         for (k, v) in self.extra_env.iter() {
             cmd = cmd.env(k.as_slice(), v.as_ref().map(|s| s.as_slice()));
         }
-        return cmd;
+
+        cmd.env("CARGO_MANIFEST_DIR", Some(pkg.get_manifest_path().dir_path()))
+           .env("CARGO_PKG_VERSION_MAJOR",
+                Some(pkg.get_version().major.to_string()))
+           .env("CARGO_PKG_VERSION_MINOR",
+                Some(pkg.get_version().minor.to_string()))
+           .env("CARGO_PKG_VERSION_PATCH",
+                Some(pkg.get_version().patch.to_string()))
+           .env("CARGO_PKG_VERSION_PRE",
+                pre_version_component(pkg.get_version()))
+           .cwd(pkg.get_root())
+    }
+}
+
+fn pre_version_component(v: &Version) -> Option<String> {
+    if v.pre.is_empty() {
+        return None;
     }
+
+    let mut ret = String::new();
+
+    for (i, x) in v.pre.iter().enumerate() {
+        if i != 0 { ret.push_char('.') };
+        ret.push_str(x.to_string().as_slice());
+    }
+
+    Some(ret)
 }
index 360afb88f45e628e7fa476a8a39e585b19665b2b..cfa62bdc24327288e34e43231f190a4b696b613f 100644 (file)
@@ -1,6 +1,5 @@
 use std::collections::{HashMap, HashSet};
 use std::str;
-use semver::Version;
 
 use core::{SourceMap, Package, PackageId, PackageSet, Resolve, Target};
 use util::{mod, CargoResult, ChainError, internal, Config, profile, Require};
@@ -147,32 +146,7 @@ impl<'a, 'b> Context<'a, 'b> {
         self.compilation.root_output = self.layout(KindTarget).proxy().dest().clone();
         self.compilation.deps_output = self.layout(KindTarget).proxy().deps().clone();
 
-        let env = &mut self.compilation.extra_env;
-        env.insert("CARGO_PKG_VERSION_MAJOR".to_string(),
-                   Some(pkg.get_version().major.to_string()));
-        env.insert("CARGO_PKG_VERSION_MINOR".to_string(),
-                   Some(pkg.get_version().minor.to_string()));
-        env.insert("CARGO_PKG_VERSION_PATCH".to_string(),
-                   Some(pkg.get_version().patch.to_string()));
-        env.insert("CARGO_PKG_VERSION_PRE".to_string(),
-                   pre_version_component(pkg.get_version()));
-
         return Ok(());
-
-        fn pre_version_component(v: &Version) -> Option<String> {
-            if v.pre.is_empty() {
-                return None;
-            }
-
-            let mut ret = String::new();
-
-            for (i, x) in v.pre.iter().enumerate() {
-                if i != 0 { ret.push_char('.') };
-                ret.push_str(x.to_string().as_slice());
-            }
-
-            Some(ret)
-        }
     }
 
     fn build_requirements(&mut self, pkg: &'a Package, target: &'a Target,
index 0bb383d6b53fd176e7c992380f744c36fd9037f0..a4644e1747b4b75bdb91620fc740fa41ad5519b5 100644 (file)
@@ -438,7 +438,6 @@ pub fn process<T: ToCStr>(cmd: T, pkg: &Package, cx: &Context) -> ProcessBuilder
 
     // We want to use the same environment and such as normal processes, but we
     // want to override the dylib search path with the one we just calculated.
-    cx.compilation.process(cmd).cwd(pkg.get_root())
-                               .env(DynamicLibrary::envvar(),
-                                    Some(search_path.as_slice()))
+    cx.compilation.process(cmd, pkg)
+                  .env(DynamicLibrary::envvar(), Some(search_path.as_slice()))
 }
index b48641e33a67a343c33b588096cb383cc4e3f001..d1c0ad13e7e47599159361a2c2f11bf76a90cefe 100644 (file)
@@ -21,7 +21,7 @@ pub fn run_tests(manifest_path: &Path,
             Some(path) => path,
             None => exe.clone(),
         };
-        let cmd = compile.process(exe).args(args);
+        let cmd = compile.process(exe, &package).args(args);
         try!(options.shell.concise(|shell| {
             shell.status("Running", to_display.display().to_string())
         }));
@@ -43,7 +43,7 @@ pub fn run_tests(manifest_path: &Path,
 
     for (lib, name) in libs {
         try!(options.shell.status("Doc-tests", name));
-        let mut p = compile.process("rustdoc")
+        let mut p = compile.process("rustdoc", &package)
                            .arg("--test").arg(lib)
                            .arg("--crate-name").arg(name)
                            .arg("-L").arg(&compile.root_output)
index 9f916ea4194df624a7e3708ce5783f0d49ede8a9..7bf37e965c8c493b7f88a7aabb880d3920ff0203 100644 (file)
@@ -799,21 +799,24 @@ test!(crate_version_env_vars {
             static VERSION_MINOR: &'static str = env!("CARGO_PKG_VERSION_MINOR");
             static VERSION_PATCH: &'static str = env!("CARGO_PKG_VERSION_PATCH");
             static VERSION_PRE: &'static str = env!("CARGO_PKG_VERSION_PRE");
+            static CARGO_MANIFEST_DIR: &'static str = env!("CARGO_MANIFEST_DIR");
 
             fn main() {
-                let s = format!("{}-{}-{} @ {}", VERSION_MAJOR, VERSION_MINOR,
-                                VERSION_PATCH, VERSION_PRE);
+                let s = format!("{}-{}-{} @ {} in {}", VERSION_MAJOR,
+                                VERSION_MINOR, VERSION_PATCH, VERSION_PRE,
+                                CARGO_MANIFEST_DIR);
                 assert_eq!(s, foo::version());
                 println!("{}", s);
             }
         "#)
         .file("src/lib.rs", r#"
             pub fn version() -> String {
-                format!("{}-{}-{} @ {}",
+                format!("{}-{}-{} @ {} in {}",
                         env!("CARGO_PKG_VERSION_MAJOR"),
                         env!("CARGO_PKG_VERSION_MINOR"),
                         env!("CARGO_PKG_VERSION_PATCH"),
-                        env!("CARGO_PKG_VERSION_PRE"))
+                        env!("CARGO_PKG_VERSION_PRE"),
+                        env!("CARGO_MANIFEST_DIR"))
             }
         "#);
 
@@ -821,7 +824,8 @@ test!(crate_version_env_vars {
 
     assert_that(
       process(p.bin("foo")),
-      execs().with_stdout("0-5-1 @ alpha.1\n"));
+      execs().with_stdout(format!("0-5-1 @ alpha.1 in {}\n",
+                                  p.root().display()).as_slice()));
 
     assert_that(p.process(cargo_dir().join("cargo-test")), execs().with_status(0));
 })